﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AvalonDock;
using SharpPcap;
using SharpPcap.LibPcap;
using SharpPcap.WinPcap;
using System.Data;
using System.IO;
using Microsoft.Win32;
using System.Windows.Threading;
using System.Timers;

namespace Scope_EtherCAT
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private LibPcapLiveDevice Device_Selected;  // Device sélectionné
        private LibPcapLiveDeviceList Device_List = LibPcapLiveDeviceList.Instance; // Liste des devices dispo
        private DataTable tblDevice = new DataTable("ListDevice"); // DataTable pour l'affichage de la liste des devices
        private string FileName;
        private bool bSave = false;
        private CaptureFileWriterDevice cptFileWrite;
        private string tmpStat;
        private Timer tRefreshDisp;

        private delegate void SetMyLabel(string sValue);

        public MainWindow()
        {      
            Device_Selected = Properties.Settings.Default.Device;
            // Ajout des colones liées au DataGrid
            tblDevice.Columns.Add("ID", typeof(int));
            tblDevice.Columns.Add("Name", typeof(string));
            tblDevice.Columns.Add("Description", typeof(string));
            InitializeComponent();
            tRefreshDisp = new Timer(500);
            tRefreshDisp.Elapsed +=new ElapsedEventHandler(tRefreshDisp_Elapsed);
        }

        /// <summary>
        /// Rempli ou vide le tableau des devices dispo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridPort_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            int i = 0;
            if (dataGridPort.IsVisible == true)
            {
                foreach (LibPcapLiveDevice device in Device_List)
                {
                    tblDevice.Rows.Add(new Object[] { i, device.Name, device.Description});
                    i++;
                }
                dataGridPort.DataContext = tblDevice;
            }
            else
            {
                tblDevice.Rows.Clear();
                dataGridPort.DataContext = tblDevice;
            }
        }

        /// <summary>
        /// Sauvegarde des Parametres de l'application à la fermeture.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Properties.Settings.Default.Save();
        }

        private void dataGridPort_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int indx = dataGridPort.SelectedIndex;  // Récupère le numéro d'index de la ligne sélectionnée
            if (indx >= 0)
            {
                int temp = (int)tblDevice.Rows[indx].ItemArray[0];
                Device_Selected = Device_List[temp];
                Properties.Settings.Default.Device = Device_Selected;
            }
        }

        private void imgStart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (Device_Selected != null)
            {
                Device_Selected.OnPacketArrival += new PacketArrivalEventHandler(Device_Selected_OnPacketArrival);
                
                Device_Selected.Open(DeviceMode.Promiscuous,1000);
                if (bSave & cptFileWrite==null)
                    cptFileWrite = new CaptureFileWriterDevice(Device_Selected, FileName);
                Device_Selected.StartCapture();
                tRefreshDisp.Start();
                elpsRecording.Visibility = System.Windows.Visibility.Visible;
                lblStatistic.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void imgPause_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

        }

        private void imgStop_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Device_Selected.StopCapture();
            elpsRecording.Visibility = System.Windows.Visibility.Hidden;
            lblStatistic.Visibility = System.Windows.Visibility.Hidden;
            tRefreshDisp.Stop();
            if (cptFileWrite != null)
                if (cptFileWrite.Opened==true)
                    cptFileWrite.Close();
        }

        private void menu_FileNew_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "Pcap files (*.pcap)|*.pcap";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == true)
            {
                if (saveFileDialog1.OpenFile() != null)
                {
                    FileName = saveFileDialog1.FileName;
                    bSave = true;
                }
                else
                {
                    FileName = null;
                    bSave = false;
                }
            }
        }

        public void Device_Selected_OnPacketArrival(object sender, CaptureEventArgs e)
        {            
            tmpStat = "Packets Dropped : " + Device_Selected.Statistics.DroppedPackets.ToString() + " - Received : " + Device_Selected.Statistics.ReceivedPackets.ToString();
            
            if (bSave)
                cptFileWrite.Write(e.Packet);
        }

        public void update_Statistic(string sValue)
        {
            lblStatistic.Content = sValue;
        }


        private void tRefreshDisp_Elapsed(object source, ElapsedEventArgs e)
        {
            this.Dispatcher.Invoke(DispatcherPriority.Background, new SetMyLabel(update_Statistic), tmpStat);
        }
    }
}
